home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xinu.arc / XINUC3.C < prev   
Text File  |  1986-01-03  |  15KB  |  567 lines

  1. /* queue.c - dequeue, enqueue  p. 46 */
  2.  
  3. # include    <conf.h>
  4. # include    <kernel.h>
  5. # include    <q.h>
  6.  
  7. /*-----------------------------------------------------------------------------
  8.  * enqueue  --  insert an item at the tail of a list
  9.  *-----------------------------------------------------------------------------
  10.  */
  11. int    enqueue(item,tail)
  12.     int    item;            /* item to enqueue on a list         */
  13.     int    tail;            /* index in q of list tail           */
  14. {
  15.     struct qent    *tptr;        /* points to tail entry              */
  16.     struct qent    *mptr;        /* points to item entry              */
  17.  
  18.     tptr = &q[tail];
  19.     mptr = &q[item];
  20.     mptr->qnext = tail;
  21.     mptr->qprev = tptr->qprev;
  22.     q[tptr->qprev].qnext = item;
  23.     tptr->qprev = item;
  24.     return(item);
  25. }
  26.  
  27. /*-----------------------------------------------------------------------------
  28.  * dequeue  --  remove an item from a list and return it
  29.  *-----------------------------------------------------------------------------
  30.  */
  31. int    dequeue(item)
  32.     int    item;
  33. {
  34.     struct qent    *mptr;        /* pointer to q entry for item       */
  35.  
  36.     mptr = &q[item];
  37.     q[mptr->qprev].qnext = mptr->qnext;
  38.     q[mptr->qnext].qprev = mptr->qprev;
  39.     return(item);
  40. }
  41. /* rdisk.c - rdinit rdopen rdread rdwrite */
  42.  
  43. # include    <conf.h>
  44. # include    <kernel.h>
  45. # include    <disk.h>
  46. # include    <file.h>
  47. # include    <dir.h>
  48.  
  49. # ifdef    Ndsk
  50. struct dsblk    dstab[Ndsk];
  51. # endif
  52. int    dskdbp, dskrbp;
  53.  
  54. /*-----------------------------------------------------------------------------
  55.  *  rdinit  --  initialize ram disk device
  56.  *-----------------------------------------------------------------------------
  57.  */
  58. rdinit(devptr)
  59.     struct devsw    *devptr;
  60. {
  61.     struct dsblk    *dsptr;
  62.     struct dtc    *dtptr;
  63.     int    status;
  64.     int    ps;    
  65.  
  66.     ps = disable();
  67.     dsptr = &dstab[devptr->dvminor];
  68.     devptr->dvioblk = (char *)dsptr;
  69.     dsptr->dcsr    = (struct dtc *)devptr->dvcsr;
  70.     dsptr->dreqlst = DRNULL;
  71.     dsptr->dnum    = devptr->dvnum;
  72.     dsptr->dibsem  = screate(1);
  73.     dsptr->dflsem  = screate(1);
  74.     dsptr->ddirsem = screate(1);
  75.     dsptr->dnfiles = 0;
  76.     dsptr->ddir    = (char *)getbuf(dskdbp);
  77. è    /* read directory block; setup read command then start interface */
  78.  
  79.     rdread ( devptr, dsptr->ddir, DIRBLK );
  80.     restore(ps);
  81.     return(OK);
  82. }
  83.  
  84.  
  85. /*-----------------------------------------------------------------------------
  86.  *  rdopen  --  open/create a file on the specified ram disk device
  87.  *-----------------------------------------------------------------------------
  88.  */
  89. rdopen(devptr, filenam, mode)
  90.     struct devsw    *devptr;
  91.     char    *filenam;
  92.     char    *mode;
  93. {
  94.     struct dir    *dirptr;
  95.     struct flblk    *flptr;
  96.     struct fdes    *fdptr;
  97.     DBADDR    dba;
  98.     int    mbits, findex;
  99.     int    retcode;
  100.     int    ps;
  101.     extern struct fdes    *dfdsrch();
  102.  
  103.     ps = disable();
  104.     dirptr = dsdirec(devptr->dvnum);
  105.     if ((mbits=dfckmd(mode)) == SYSERR)
  106.         retcode = SYSERR;
  107.     else if ((fdptr=dfdsrch(devptr->dvioblk,filenam,mbits)) 
  108.                 == (struct fdes *)SYSERR)
  109.         retcode = SYSERR;
  110.     else if ((findex=dfalloc()) == SYSERR)
  111.         retcode = SYSERR;
  112.     else  {
  113.         flptr = &fltab[findex];
  114.         flptr->fl_dev = devptr->dvnum;
  115.         flptr->fl_dent = fdptr;
  116.         flptr->fl_mode = mbits & FLRW;
  117.         flptr->fl_iba = fdptr->fdiba;
  118.         ibget(flptr->fl_dev,flptr->fl_iba,&(flptr->fl_iblk));
  119.         flptr->fl_pos = 0L;
  120.         flptr->fl_dch = FALSE;
  121.         dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum = 0];
  122.         if (dba != DBNULL)  {
  123.             read(flptr->fl_dev, flptr->fl_buff, dba);
  124.             flptr->fl_bptr = flptr->fl_buff;
  125.         }  else
  126.             flptr->fl_bptr = &flptr->fl_buff[DBUFSIZ];
  127.         retcode = flptr->fl_id;
  128.     }
  129.     restore(ps);
  130.     return(retcode);
  131.  
  132. /*-----------------------------------------------------------------------------
  133.  *  rdread  --  read from ram disk
  134.  *-----------------------------------------------------------------------------
  135.  */
  136. rdread(devptr, buff, block)
  137.     struct devsw    *devptr;
  138.     char    *buff;
  139.     DBADDR    block;
  140. {
  141.     char    *from, *to;
  142.     int    i;
  143.  
  144.     from = (char *)((long)block * (long)DBUFSIZ + (long)devptr->dvcsr );
  145.     to = buff;
  146.     for ( i = 0; i < DBUFSIZ; i++ )  {
  147.         *to++ = *from++;
  148.     }
  149.     return(OK);
  150. }
  151.  
  152.  
  153. /*-----------------------------------------------------------------------------
  154.  *  rdwrite  --  write to ram disk
  155.  *-----------------------------------------------------------------------------
  156.  */
  157. rdwrite(devptr, buff, block)
  158.     struct devsw    *devptr;
  159.     char    *buff;
  160.     DBADDR    block;
  161. {
  162.     char    *from, *to;
  163.     int    i;
  164.  
  165.     from = buff;
  166.     to = (char *)((long)block * (long)DBUFSIZ + (long)devptr->dvcsr );
  167.     for ( i = 0; i < DBUFSIZ; i++ )  {
  168.         *to++ = *from++;
  169.     }
  170.     freebuf(buff);
  171.     return(OK);
  172. }
  173. /* read.c - read  p. 145 */
  174.  
  175. # include    <conf.h>
  176. # include    <kernel.h>
  177. # include    <io.h>
  178.  
  179. /*-----------------------------------------------------------------------------
  180.  *  read  --  read one or more bytes from a device
  181.  *-----------------------------------------------------------------------------
  182.  */
  183. read(descrp, buff, count)
  184.     int    descrp, count;
  185.     char    *buff;
  186. {
  187.     struct devsw    *devptr;
  188.  
  189.     if (isbaddev(descrp))
  190.         return(SYSERR);
  191.     devptr = &devtab[descrp];
  192.     return ((*devptr->dvread)(devptr,buff,count));
  193. }
  194. /* ready.c - ready  p. 62 */
  195.  
  196. # include    <conf.h>
  197. # include    <kernel.h>
  198. # include    <proc.h>
  199. # include    <q.h>
  200.  
  201. /*-----------------------------------------------------------------------------
  202.  * ready  --  make a process eligible for CPU service
  203.  *-----------------------------------------------------------------------------
  204.  */
  205. int    ready (pid, resch)
  206.     int    pid;            /* id of process to make ready       */
  207.     int    resch;            /* reschedule afterward?             */
  208. {
  209.     register struct pentry    *pptr;
  210.  
  211.     if (isbadpid(pid))
  212.         return(SYSERR);
  213.     pptr = &proctab[pid];
  214.     pptr->pstate = PRREADY;
  215.     insert(pid,rdyhead,pptr->pprio);
  216.     if (resch)
  217.         resched();
  218.     return(OK);
  219. }
  220. /* receive.c - receive  p. 97 */
  221.  
  222. # include    <conf.h>
  223. # include    <kernel.h>
  224. # include    <proc.h>
  225.  
  226. /*-----------------------------------------------------------------------------
  227.  *  receive  --  wait for a message and return it
  228.  *-----------------------------------------------------------------------------
  229.  */
  230. SYSCALL    receive()
  231. {
  232.     struct pentry    *pptr;
  233.     int    msg;
  234.     char    ps;
  235.  
  236.     disable(ps);
  237.     pptr = &proctab[currpid];
  238.     if (pptr->phasmsg == 0)  {    /* if no message, wait for one       */
  239.         pptr->pstate = PRRECV;
  240.         resched();
  241.     }
  242.     msg = pptr->pmsg;        /* retrieve message                  */
  243.     pptr->phasmsg = 0;
  244.     restore(ps);
  245.     return(msg);
  246. }
  247. /* recvclr.c - recvclr  p. 98 */
  248.  
  249. # include    <conf.h>
  250. # include    <kernel.h>
  251. # include    <proc.h>
  252.  
  253. /*-----------------------------------------------------------------------------
  254.  *  recvclr  --  clear messages, returning waiting message ( if any )
  255.  *-----------------------------------------------------------------------------
  256.  */
  257. SYSCALL    recvclr()
  258. {
  259.     char    ps;
  260.     int    msg;
  261.  
  262.     disable(ps);
  263.     if (proctab[currpid].phasmsg)  {    /* existing message          */
  264.         proctab[currpid].phasmsg = 0;
  265.         msg = proctab[currpid].pmsg;
  266.     }  else
  267.         msg = OK;
  268.     restore(ps);
  269.     return(msg);
  270. }
  271. /* resched.c - resched  p. 58 */
  272.  
  273. # include    <conf.h>
  274. # include    <kernel.h>
  275. # include    <proc.h>
  276. # include    <q.h>
  277.  
  278. /*-----------------------------------------------------------------------------
  279.  * resched  --  reschedule processor to highest priority ready process
  280.  *
  281.  * Notes:       Upon entry, currpid gives current process id.
  282.  *              Proctab[currpid].pstate gives correct NEXT state for
  283.  *                      current process if other than PRREADY.
  284.  *-----------------------------------------------------------------------------
  285.  */
  286. int    resched()
  287. {
  288.     register struct pentry    *optr;    /* pointer to old process entry      */
  289.     register struct pentry    *nptr;    /* pointer to new process entry      */
  290.  
  291.     /* no switch needed if current process priority higher than next */
  292.  
  293.     if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
  294.        (lastkey(rdytail)<optr->pprio))
  295.         return ( OK );
  296.  
  297.     /* force context switch */
  298.  
  299.     if (optr->pstate == PRCURR)  {
  300.         optr->pstate = PRREADY;
  301.         insert(currpid,rdyhead,optr->pprio);
  302.     }
  303.  
  304.     /* remove highest priority process at end of ready list */
  305.  
  306.     nptr = &proctab[ (currpid = getlast(rdytail)) ];
  307.     nptr->pstate = PRCURR;        /* mark it currently running         */
  308. # ifdef    RTCLOCK
  309.     preempt = QUANTUM;        /* reset preemption counter          */
  310. # endif
  311.     ctxsw(optr->pregs,nptr->pregs);
  312.  
  313.     /* the old process returns here when resumed. */
  314.     return(OK);
  315. }
  316. /* resume.c - resume  p. 66 */
  317.  
  318. # include    <conf.h>
  319. # include    <kernel.h>
  320. # include    <proc.h>
  321.  
  322. /*-----------------------------------------------------------------------------
  323.  * resume  --  unsuspend a process, making it ready; return the priority
  324.  *-----------------------------------------------------------------------------
  325.  */
  326. SYSCALL    resume(pid)
  327.     int    pid;
  328. {
  329.     char    ps;            /* saved processor status            */
  330.     struct pentry    *pptr;        /* pointer to proccess table entry   */
  331.     int    prio;            /* priority to return                */
  332.  
  333.     disable(ps);
  334.     if (isbadpid(pid) || (pptr = &proctab[pid])->pstate != PRSUSP)  {
  335.         restore(ps);
  336.         return(SYSERR);
  337.     }
  338.     prio = pptr->pprio;
  339.     ready(pid, RESCHYES);
  340.     restore(ps);
  341.     return(prio);
  342. }
  343. /* screate.c - screate, newsem  p. 88 */
  344.  
  345. # include    <conf.h>
  346. # include    <kernel.h>
  347. # include    <proc.h>
  348. # include    <q.h>
  349. # include    <sem.h>
  350.  
  351. /*-----------------------------------------------------------------------------
  352.  * screate  --  create and initialize a semaphore, returning its id
  353.  *-----------------------------------------------------------------------------
  354.  */
  355. SYSCALL    screate(count)
  356.     int    count;            /* initial count (>=0)               */
  357. {
  358.     char    ps;
  359.     int    sem;
  360.  
  361.     disable(ps);
  362.     if ( count<0 || (sem=newsem())==SYSERR )  {
  363.         restore(ps);
  364.         return(SYSERR);
  365.     }
  366.     semaph[sem].semcnt = count;
  367.     /* sqhead and sqtail were initialized at system startup */
  368.     restore(ps);
  369.     return(sem);
  370. }
  371.  
  372. /*-----------------------------------------------------------------------------
  373.  * newsem  --  allocate an unused semaphore and return its index
  374.  *-----------------------------------------------------------------------------
  375.  */
  376. LOCAL    newsem()
  377. {
  378.     int    sem;
  379.     int    i;
  380.  
  381.     for (i=0 ; i<NSEM ; i++)  {
  382.         sem = nextsem--;
  383.         if (nextsem < 0)
  384.             nextsem = NSEM-1;
  385.         if (semaph[sem].sstate==SFREE)  {
  386.             semaph[sem].sstate = SUSED;
  387.             return(sem);
  388.         }
  389.     }
  390.     return(SYSERR);
  391. }
  392. /* sdelete.c - sdelete  p. 89 */
  393.  
  394. # include    <conf.h>
  395. # include    <kernel.h>
  396. # include    <proc.h>
  397. # include    <q.h>
  398. # include    <sem.h>
  399.  
  400. /*-----------------------------------------------------------------------------
  401.  * sdelete  --  delete a semaphore by releasing its table entry
  402.  *-----------------------------------------------------------------------------
  403.  */
  404. SYSCALL    sdelete(sem)
  405.     int    sem;
  406. {
  407.     char    ps;
  408.     int    pid;
  409.     struct sentry    *sptr;        /* address of sem to free           */
  410.  
  411.     disable(ps);
  412.     if (isbadsem(sem) || semaph[sem].sstate==SFREE)  {
  413.         restore(ps);
  414.         return(SYSERR);
  415.     }
  416.     sptr = &semaph[sem];
  417.     sptr->sstate = SFREE;
  418.     if (nonempty(sptr->sqhead))  {    /* free waiting process             */
  419.         while ((pid=getfirst(sptr->sqhead)) != EMPTY)
  420.             ready(pid,RESCHNO);
  421.         resched();
  422.     }
  423.     restore(ps);
  424.     return(OK);
  425. }
  426. /* seek.c - seek  p. 148 */
  427.  
  428. # include    <conf.h>
  429. # include    <kernel.h>
  430. # include    <io.h>
  431.  
  432. /*-----------------------------------------------------------------------------
  433.  *  seek  --  position a device (very common special case of control)
  434.  *-----------------------------------------------------------------------------
  435.  */
  436. seek(descrp, pos)
  437.     int    descrp;
  438.     long    pos;
  439. {
  440.     struct devsw    *devptr;
  441.  
  442.     if (isbaddev(descrp))
  443.         return(SYSERR);
  444.     devptr = &devtab[descrp];
  445.     return ((*devptr->dvseek)(devptr,pos));
  446. }
  447. /* send.c - send  p. 96 */
  448.  
  449. # include    <conf.h>
  450. # include    <kernel.h>
  451. # include    <proc.h>
  452.  
  453. /*-----------------------------------------------------------------------------
  454.  *  send  --  send a message to another process
  455.  *-----------------------------------------------------------------------------
  456.  */
  457. SYSCALL    send(pid, msg)
  458.     int    pid;
  459.     int    msg;
  460. {
  461.     struct pentry    *pptr;        /* receiver's process table address  */
  462.     char    ps;
  463.  
  464.     disable(ps);
  465.     if (isbadpid(pid) || ((pptr= &proctab[pid])->pstate == PRFREE)
  466.        || pptr->phasmsg != 0)  {
  467.         restore(ps);
  468.         return(SYSERR);
  469.     }
  470.     pptr->pmsg = msg;        /* deposit message                   */
  471.     pptr->phasmsg++;
  472.     if (pptr->pstate == PRRECV)    /* if receiver waits, start it       */
  473.         ready(pid, RESCHYES);
  474.     restore(ps);
  475.     return(OK);
  476. }
  477. /* signal.c - signal  p. 86 */
  478.  
  479. # include    <conf.h>
  480. # include    <kernel.h>
  481. # include    <proc.h>
  482. # include    <q.h>
  483. # include    <sem.h>
  484.  
  485. /*-----------------------------------------------------------------------------
  486.  * signal  --  signal a semaphore, releasing one waiting process
  487.  *-----------------------------------------------------------------------------
  488.  */
  489. SYSCALL    signal(sem)
  490.     register int    sem;
  491. {
  492.     register struct sentry    *sptr;
  493.     char    ps;
  494.  
  495.     disable(ps);
  496.     if (isbadsem(sem) || (sptr = &semaph[sem])->sstate==SFREE)  {
  497.         restore(ps);
  498.         return(SYSERR);
  499.     }
  500.     if ((sptr->semcnt++) < 0)
  501.         ready(getfirst(sptr->sqhead),RESCHYES);
  502.     restore(ps);
  503.     return(OK);
  504. }
  505. /* sleep.c - sleep  p. 132 */
  506.  
  507. # include    <conf.h>
  508. # include    <kernel.h>
  509. # include    <proc.h>
  510. # include    <q.h>
  511. # include    <sleep.h>
  512.  
  513. /*-----------------------------------------------------------------------------
  514.  *  sleep  --  delay the calling process n seconds
  515.  *-----------------------------------------------------------------------------
  516.  */
  517. SYSCALL    sleep(n)
  518.     int    n;
  519. {
  520.     if (n<0 || clkruns==0)
  521.         return(SYSERR);
  522.     if (n == 0)  {
  523.         resched();
  524.         return(OK);
  525.     }
  526.     while (n >= 1000)  {
  527.         sleep10(10000);
  528.         n -= 1000;
  529.     }
  530.     if (n > 0)
  531.         sleep10(10*n);
  532.     return(OK);
  533. }
  534. /* sleep10.c - sleep10  p. 129 */
  535.  
  536. # include    <conf.h>
  537. # include    <kernel.h>
  538. # include    <proc.h>
  539. # include    <q.h>
  540. # include    <sleep.h>
  541.  
  542. /*-----------------------------------------------------------------------------
  543.  *  sleep10  --  delay the caller for a time specified in tenths of seconds
  544.  *-----------------------------------------------------------------------------
  545.  */
  546. SYSCALL    sleep10(n)
  547.     int    n;
  548. {
  549.     char    ps;
  550.  
  551.     if (n < 0 || clkruns==0)
  552.         return(SYSERR);
  553.     if (n == 0)  {
  554.         resched();        /* sleep10(0) -> end time slice      */
  555.         return(OK);
  556.     }
  557.     disable(ps);
  558.     insertd(currpid,clockq,n);
  559.     slnempty = TRUE;
  560.     sltop = &q[q[clockq].qnext].qkey;
  561.     proctab[currpid].pstate = PRSLEEP;
  562.     resched();
  563.     restore(ps);
  564.     return(OK);
  565. }
  566.